# -*- coding: utf-8 -*-
# @Time    : 2019/8/23 21:59
# @Author  : zhoujun
import time
import json
import cv2
import torch
import numpy as np
import matplotlib.pyplot as plt


def setup_logger(log_file_path: str = None):
    import logging
    from colorlog import ColoredFormatter
    logging.basicConfig(filename=log_file_path,
                        format='%(asctime)s %(levelname)-8s %(filename)s[line:%(lineno)d]: %(message)s',
                        # 定义输出log的格式
                        datefmt='%Y-%m-%d %H:%M:%S', )
    """Return a logger with a default ColoredFormatter."""
    formatter = ColoredFormatter(
        "%(asctime)s %(log_color)s%(levelname)-8s %(reset)s %(filename)s[line:%(lineno)d]: %(message)s",
        datefmt='%Y-%m-%d %H:%M:%S',
        reset=True,
        log_colors={
            'DEBUG': 'blue',
            'INFO': 'green',
            'WARNING': 'yellow',
            'ERROR': 'red',
            'CRITICAL': 'red',
        })

    logger = logging.getLogger('PAN')
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG)
    logger.info('logger init finished')
    return logger


# --exeTime
def exe_time(func):
    def newFunc(*args, **args2):
        t0 = time.time()
        back = func(*args, **args2)
        print("{} cost {:.3f}s".format(func.__name__, time.time() - t0))
        return back

    return newFunc


def save_json(data, json_path):
    with open(json_path, mode='w', encoding='utf8') as f:
        json.dump(data, f, indent=4)


def load_json(json_path):
    with open(json_path, mode='r', encoding='utf8') as f:
        data = json.load(f)
    return data


def show_img(imgs: np.ndarray, color=False):
    if (len(imgs.shape) == 3 and color) or (len(imgs.shape) == 2 and not color):
        imgs = np.expand_dims(imgs, axis=0)
    for img in imgs:
        plt.figure()
        plt.imshow(img, cmap=None if color else 'gray')


def draw_bbox(img_path, result, color=(255, 0, 0), thickness=2):
    if isinstance(img_path, str):
        img_path = cv2.imread(img_path)
        # img_path = cv2.cvtColor(img_path, cv2.COLOR_BGR2RGB)
    img_path = img_path.copy()
    for point in result:
        point = point.astype(int)
        cv2.line(img_path, tuple(point[0]), tuple(point[1]), color, thickness)
        cv2.line(img_path, tuple(point[1]), tuple(point[2]), color, thickness)
        cv2.line(img_path, tuple(point[2]), tuple(point[3]), color, thickness)
        cv2.line(img_path, tuple(point[3]), tuple(point[0]), color, thickness)
    return img_path


def cal_text_score(texts, gt_texts, training_masks, running_metric_text):
    training_masks = training_masks.data.cpu().numpy()
    pred_text = torch.sigmoid(texts).data.cpu().numpy() * training_masks
    pred_text[pred_text <= 0.5] = 0
    pred_text[pred_text > 0.5] = 1
    pred_text = pred_text.astype(np.int32)
    gt_text = gt_texts.data.cpu().numpy() * training_masks
    gt_text = gt_text.astype(np.int32)
    running_metric_text.update(gt_text, pred_text)
    score_text, _ = running_metric_text.get_scores()
    return score_text


def cal_kernel_score(kernel, gt_kernel, gt_texts, training_masks, running_metric_kernel):
    mask = (gt_texts * training_masks.float()).data.cpu().numpy()
    pred_kernel = torch.sigmoid(kernel).data.cpu().numpy()
    pred_kernel[pred_kernel <= 0.5] = 0
    pred_kernel[pred_kernel > 0.5] = 1
    pred_kernel = (pred_kernel * mask).astype(np.int32)
    gt_kernel = gt_kernel.data.cpu().numpy()
    gt_kernel = (gt_kernel * mask).astype(np.int32)
    running_metric_kernel.update(gt_kernel, pred_kernel)
    score_kernel, _ = running_metric_kernel.get_scores()
    return score_kernel



def order_points_clockwise(pots):
    # 这个函数会改点，产生最小外接平行四边形
    ## bb: [x1, y1, x2, y2.......]
    bb=pots.reshape(8)
    points = []
#     print(len(bb)/2)
    for i in range(int(len(bb)/2)):
        points.append([int(bb[2*i]), int(bb[2*i+1])])
    bounding_box = cv2.minAreaRect(np.array(points))
    points = cv2.boxPoints(bounding_box)
    points = list(points)
    ps = sorted(points,key = lambda x:x[0])

    if ps[1][1] > ps[0][1]:
        px1 = ps[0][0]
        py1 = ps[0][1]
        px4 = ps[1][0]
        py4 = ps[1][1]
    else:
        px1 = ps[1][0]
        py1 = ps[1][1]
        px4 = ps[0][0]
        py4 = ps[0][1]
    if ps[3][1] > ps[2][1]:
        px2 = ps[2][0]
        py2 = ps[2][1]
        px3 = ps[3][0]
        py3 = ps[3][1]
    else:
        px2 = ps[3][0]
        py2 = ps[3][1]
        px3 = ps[2][0]
        py3 = ps[2][1]

    return np.array([px1, py1, px2, py2, px3, py3, px4, py4]).reshape(4,2)

#
# def CalAngle(v1, v2):
#     # v1旋转到v2，逆时针方向
#     # 2个向量模的乘积
#     TheNorm = np.linalg.norm(v1) * np.linalg.norm(v2)
#     # 叉乘
#     rho = np.rad2deg(np.arcsin(np.cross(v1, v2) / TheNorm))
#     # 点乘
#     theta = np.rad2deg(np.arccos(np.dot(v1, v2) / TheNorm))
#     if rho < 0:
#         return 360 - theta
#     else:
#         return theta

#
# def order_points_clockwise(pts):
#     # 这个函数不会改点
#     x_center, y_center = pts.sum(axis=0) / 4
#     new_v = pts - [x_center, y_center]
#
#     rect = np.zeros((4, 2), dtype="float32")
#     s = pts.sum(axis=1)
#     min_id = np.argmin(s)
#     rect[0] = pts[np.argmin(s)]
#
#     sort_array = np.zeros(4)  # 产生排序
#     for i in range(4):
#         if i == min_id:
#             continue
#         sort_array[i] = CalAngle(new_v[min_id], new_v[i])  # 按顺序产生角度
#     arg_value = np.argsort(sort_array)
#     for i in range(1, 4):
#         rect[i] = pts[arg_value[i]]
#     return rect


if __name__ == '__main__':
    box = np.array([382, 1080, 443, 999, 423, 1014, 362, 1095]).reshape(-1, 2)
    # box = np.array([0, 4, 2, 2, 0, 8, 4, 4]).reshape(-1, 2)
    # box = np.array([0, 0, 2, 2, 0, 4, 4, 4]).reshape(-1, 2)
    from scipy.spatial import ConvexHull

    # print(order_points_colckwise(box))
    print(order_points_clockwise(box))
